+++ /dev/null
-Copyright (c) 2001, Pabs (pabs3@zip.to)\r
-All rights reserved.\r
-\r
-Redistribution and use in source and binary forms, with or without\r
-modification, are permitted provided that the following conditions\r
-are met:\r
-\r
-Redistributions of source code must retain the above copyright notice,\r
-this list of conditions and the following disclaimer.\r
-Redistributions in binary form must reproduce the above copyright\r
-notice, this list of conditions and the following disclaimer in the\r
-documentation and/or other materials provided with the distribution.\r
-\r
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
-HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
+++ /dev/null
-Copyright (c) 2002, Pabs (pabs3@zip.to)\r
-All rights reserved.\r
-\r
-Redistribution and use in source and binary forms, with or without\r
-modification, are permitted provided that the following conditions\r
-are met:\r
-\r
-Redistributions of source code must retain the above copyright notice,\r
-this list of conditions and the following disclaimer.\r
-Redistributions in binary form must reproduce the above copyright\r
-notice, this list of conditions and the following disclaimer in the\r
-documentation and/or other materials provided with the distribution.\r
-\r
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
-HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
+++ /dev/null
-There are two executables, with just the default output type changed:\r
-\r
-istorage-make.exe\r
- defaults to making OLE IStorages\r
- made from the distributed source with MSVC 6\r
-\r
-its-make.exe\r
- defaults to making compressed ITS ITStorages\r
- made from modified source with MSVC 6\r
-\r
-Read LICENCE.txt for conditions of distribution and modification.\r
-To use just drag a folder onto the appropriate executable/shortcut.\r
-Don't worry about the warnings saying that the times could not be set.\r
-\r
-Enjoy say i,\r
-Pabs <pabs3@zip.to>\r
-http://zip.to/pabs3/
\ No newline at end of file
+++ /dev/null
-/*Copyright by Pabs (pabs3@zip.to, http://zip.to/pabs3/) Dec 2002*/\r
-\r
-/*Licenced under the BSD sloppyright - nasty little daemons better not use this source & not attribute me*/\r
-\r
-/*Compile notes:\r
- M$VC: just open this file & press the build button or select build from the\r
- build menu since this will create a default project that does nicely\r
- GCC/Cygwin: gcc -mno-cygwin -fvtable-thunks -o istorage-make.exe istorage-make.cpp -lole32 should do the trick\r
- if w32api & mingw are set up correctly & the headers are correct\r
- GCC/Wine: You'll have to figure it out for yourself since I don't yet have\r
- access to Linux (Debian) cause I need a new HD + a DVD drive ;-)\r
-*/\r
-\r
-/* Usage:\r
- -ole\r
- convert to an OLE compound file (default)\r
- -its\r
- convert to an ITS file\r
- -its -uc\r
- don't compress (default)\r
- -its -cd\r
- compress the data after creation\r
- -its -cdp\r
- compress the data and path after creation\r
-*/\r
-\r
-/*TODO:\r
- think up a proper name\r
- Add popt/getopt processing\r
- use libOLE on non-win32 - http://chicago.sf.net\r
- Implement options for the following\r
- rename specific files to something the normal filesystem can't handle, like 0x1 characters\r
- various tar/unzip options\r
- --help --version\r
-*/\r
-\r
-\r
-#include <windows.h>\r
-#include <ole2.h>\r
-#include <stdio.h>\r
-#include <string.h>\r
-\r
-\r
-//These next few bits are from a sample available from http://www.keyworks.net/code.htm (see http://helpware.net/delphi/index.html for a Delphi sample - need to join a yahoo group first - example 10 is the one to look at)\r
-//This stuff is supposed to be documented in the MSDN, but I only found 1 page that references ITStorage & that is an error codes list\r
-DEFINE_GUID(CLSID_ITStorage, 0x5d02926a, 0x212e, 0x11d0, 0x9d, 0xf9, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);\r
-DEFINE_GUID(IID_ITStorage, 0x88cc31de, 0x27ab, 0x11d0, 0x9d, 0xf9, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);\r
-\r
-const GUID CLSID_ITStorage = { 0x5d02926a, 0x212e, 0x11d0, { 0x9d, 0xf9, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec } };\r
-const GUID IID_ITStorage = { 0x88cc31de, 0x27ab, 0x11d0, { 0x9d, 0xf9, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec} };\r
-\r
-typedef struct _ITS_Control_Data\r
-{\r
- UINT cdwControlData; // Number of DWords to follow.\r
- UINT adwControlData[1]; // Actually this will be adwControlData[cdwControlData]\r
-} ITS_Control_Data, *PITS_Control_Data;\r
-\r
-typedef enum ECompactionLev {\r
- COMPACT_DATA = 0,\r
- COMPACT_DATA_AND_PATH\r
-};\r
-\r
-DECLARE_INTERFACE_(IITStorage, IUnknown)\r
-{\r
- STDMETHOD(StgCreateDocfile) (const WCHAR* pwcsName, DWORD grfMode, DWORD reserved, IStorage** ppstgOpen) PURE;\r
- STDMETHOD(StgCreateDocfileOnILockBytes) (ILockBytes * plkbyt, DWORD grfMode, DWORD reserved, IStorage** ppstgOpen) PURE;\r
- STDMETHOD(StgIsStorageFile) (const WCHAR * pwcsName) PURE;\r
- STDMETHOD(StgIsStorageILockBytes) (ILockBytes * plkbyt) PURE;\r
- STDMETHOD(StgOpenStorage)(const WCHAR * pwcsName, IStorage * pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage ** ppstgOpen) PURE;\r
- STDMETHOD(StgOpenStorageOnILockBytes)(ILockBytes * plkbyt, IStorage * pStgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage ** ppstgOpen) PURE;\r
- STDMETHOD(StgSetTimes)(WCHAR const* lpszName, FILETIME const* pctime, FILETIME const* patime, FILETIME const* pmtime) PURE;\r
- STDMETHOD(SetControlData)(PITS_Control_Data pControlData) PURE;\r
- STDMETHOD(DefaultControlData)(PITS_Control_Data *ppControlData) PURE;\r
- STDMETHOD(Compact)(const WCHAR* pwcsName, ECompactionLev iLev) PURE;\r
-};\r
-\r
-IITStorage* ITStorage = NULL;\r
-\r
-struct OPTIONS{\r
- bool its;\r
- bool compress;\r
- ECompactionLev compression;\r
- char indentchar;\r
- char* ole_appendstring;\r
- char* its_appendstring;\r
-} options = {false,false,COMPACT_DATA,'\t',".ole",".its"};\r
-\r
-HRESULT r;\r
-\r
-void EnumFolder(char*f,IStorage* is);\r
-\r
-int main(int argc, char *argv[]){\r
- //Get an instance of the thing to call for creating chms\r
- CoInitialize(NULL);\r
- CoCreateInstance(CLSID_ITStorage, NULL, CLSCTX_INPROC_SERVER, IID_ITStorage, (void**)&ITStorage);\r
- char t[2];DWORD cdl = GetCurrentDirectory(2,t);\r
- char* current_dir = new char[cdl];\r
- if(current_dir){\r
- if(GetCurrentDirectory(cdl,current_dir)){\r
- for(int argi=1;argi<argc;argi++){\r
- if( strcmp(argv[argi],"-ole") == 0 ){ options.its = false; continue; }\r
- else if( strcmp(argv[argi],"-its") == 0 ){ options.its = true; continue; }\r
- else if( strcmp(argv[argi],"-uc") == 0 ){ options.compress = false; continue; }\r
- else if( strcmp(argv[argi],"-cd") == 0 ){\r
- options.compress = true;\r
- options.compression = COMPACT_DATA;\r
- continue;\r
- } else if( strcmp(argv[argi],"-cdp") == 0 ){\r
- options.compress = true;\r
- options.compression = COMPACT_DATA_AND_PATH;\r
- continue;\r
- }\r
- \r
- if(SetCurrentDirectory(current_dir)){\r
- if(SetCurrentDirectory(argv[argi])){\r
- if(SetCurrentDirectory("..")){\r
- unsigned int len = strlen(argv[argi]);\r
- char* appendstring = options.its ? options.its_appendstring : options.ole_appendstring;\r
- unsigned int appendstring_len = strlen(appendstring);\r
- char* file = new char[len+appendstring_len+1];\r
- if(file){\r
- strcpy(file,argv[argi]);\r
- strcpy(&file[len],appendstring);\r
- \r
- DWORD wlen = MultiByteToWideChar(CP_ACP,0,file,len+appendstring_len+1,NULL,0);\r
- WCHAR* wfile = new WCHAR[wlen+1];\r
- if(wfile){\r
- if(MultiByteToWideChar(CP_ACP,0,file,len+appendstring_len+1,wfile,wlen)){\r
- IStorage* is = NULL;\r
- if( options.its && ITStorage )\r
- r = ITStorage->StgCreateDocfile( wfile, STGM_CREATE|STGM_WRITE|STGM_SHARE_EXCLUSIVE, 0, &is );\r
- else\r
- r = StgCreateDocfile( wfile, STGM_CREATE|STGM_WRITE|STGM_SHARE_EXCLUSIVE, 0, &is );\r
- \r
- if( r == S_OK || is ){\r
- EnumFolder( argv[argi], is );\r
- is->Release(); is = NULL;\r
- if( options.its && ITStorage && options.compress ){\r
- r = ITStorage->Compact( wfile, options.compression );\r
- if(r!=S_OK) fputs("Could not compress the specified file - Ignoring & continuing\n",stderr);\r
- }\r
- } else fputs("Could not create the specified file - Ignoring & continuing\n",stderr);\r
- } else fputs("Could not convert the path to Unicode for the Unicode only StgOpenStorage - Ignoring & continuing\n",stderr);\r
- delete[]wfile; wfile = NULL;\r
- } else fputs("Could not alloc memory for the Unicode filename for the Unicode only StgCreateDocfile - Ignoring & continuing",stderr);\r
- delete[]file; file = NULL;\r
- } else fputs("Could not alloc memory for the filename - Ignoring & continuing",stderr);\r
- } else fputs("Could not enter (directory) - Ignoring & continuing\n",stderr);\r
- } else fputs("Could not enter (directory) - Ignoring & continuing\n",stderr);\r
- } else fputs("Could not reset current directory - Ignoring & continuing\n",stderr);\r
- }\r
- } else fputs("Could not get current directory - Failed\n",stderr);\r
- } else fputs("Could not allocate memory for current directory - Failed\n",stderr);\r
- if( ITStorage ) ITStorage->Release();\r
- CoUninitialize();\r
- fflush(stderr);\r
- return 0;\r
-}\r
-\r
-void EnumFolder(char*fo, IStorage* is){\r
- if(SetCurrentDirectory(fo)){\r
- HANDLE ff;WIN32_FIND_DATA wfd;\r
- ff = FindFirstFile("*",&wfd);\r
- if(ff!=INVALID_HANDLE_VALUE&&ff!=0){\r
- do{\r
- if( strcmp(wfd.cFileName,".") == 0 || strcmp(wfd.cFileName,"..") == 0 ) continue;\r
- DWORD len = strlen(wfd.cFileName)+1;\r
- DWORD wlen = MultiByteToWideChar(CP_ACP,0,wfd.cFileName,len,NULL,0);\r
- WCHAR* wpath = new WCHAR[len];\r
- if(wpath){\r
- if(MultiByteToWideChar(CP_ACP,0,wfd.cFileName,len,wpath,wlen)){\r
- if(wfd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY){\r
- IStorage* is2 = NULL;\r
- r = is->CreateStorage(wpath,STGM_WRITE|STGM_SHARE_EXCLUSIVE,0,0,&is2);\r
- if( r == S_OK && is2 ){\r
- EnumFolder(wfd.cFileName,is2);\r
- //if(S_OK!=is2->SetStateBits(wfd.dwFileAttributes)) fputs("Could not set state bits (directory) - Ignoring & continuing\n",stderr);\r
- is2->Release(); is2 = NULL;\r
- } else fputs("Could not create (directory) - Ignoring & continuing\n",stderr);\r
- } else {\r
- IStream* is2 = NULL;\r
- r = is->CreateStream(wpath,STGM_WRITE|STGM_SHARE_EXCLUSIVE,0,0,&is2);\r
- if( r == S_OK && is2 ){\r
- HANDLE f = CreateFile(wfd.cFileName,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL);\r
- if(f!=INVALID_HANDLE_VALUE&&f!=0/*Fucking lying MSDN*/){\r
- ULARGE_INTEGER fs={wfd.nFileSizeLow,wfd.nFileSizeHigh},i={0};\r
- is2->SetSize(fs);\r
- BYTE* p;\r
- DWORD nobm = (DWORD)fs.QuadPart, nobr, nobw;\r
- for(;;){\r
- p = new BYTE[nobm]; if(p)break;\r
- nobm/=2; if(!nobm)break;\r
- }\r
- if(p){\r
- bool err = false;\r
- do{\r
- if(!ReadFile(f,p,nobm,&nobr,NULL)||nobm!=nobr){fputs("Read error (file) - terminating this file\n",stderr);err=true;}//read less than asked and there was an error other than EOF - MSDN says that the compound file implementation of Read returns S_OK if the end of the stream was reached during the read\r
- nobw=0;\r
- r=is2->Write(p,nobr,&nobw);\r
- i.QuadPart+=nobw;\r
- if(r!=S_OK||nobr!=nobw){fputs("Write error (file) - terminating this file\n",stderr);err=true;}\r
- } while (i.QuadPart<fs.QuadPart&&!err);\r
- delete[]p; p = NULL;\r
- } else fputs("Could not allocate even 1 byte of mem for a buffer for transferring files - please free some memory & try again - Ignoring & continuing\n",stderr);\r
- CloseHandle(f); f = NULL;\r
- } else fputs("Could not open (file) - Ignoring & continuing\n",stderr);\r
- is2->Release(); is2 = NULL;\r
- } else fputs("Could not create (file) - Ignoring & continuing\n",stderr);\r
- }\r
- if(S_OK!=is->SetElementTimes(wpath,&wfd.ftCreationTime,&wfd.ftLastAccessTime,&wfd.ftLastWriteTime)) fputs("Could not set the creation, last modification or last access time - Ignoring & continuing\n",stderr);\r
- }\r
- }\r
- } while(FindNextFile(ff,&wfd));\r
- FindClose(ff);\r
- }\r
- SetCurrentDirectory("..");\r
- } else fputs("Could not enter (directory) - Ignoring & continuing\n",stderr);\r
-}\r
+++ /dev/null
-/*by Pabs (pabs3@zip.to, http://zip.to/pabs3) Nov 2001, April 2002*/\r
-\r
-/*Licenced under the BSD sloppyright - nasty little daemons better not use this source & not attribute me*/\r
-/*Why BSD licence? HTFSIK but seriously I wanted to get to know more open/free licences*/\r
-\r
-/*Compile notes:\r
- M$VC: just open this file & press the build button or select build from the\r
- build menu since this will create a default project that does nicely\r
- GCC/Cygwin: gcc -mno-cygwin -fvtable-thunks -lole32 -o istorage.exe istorage.cpp should do the trick\r
- if w32api & mingw are set up correctly & the headers are correct\r
- GCC/Wine: You'll have to figure it out for yourself since I don't yet have\r
- access to Linux (Debian) cause I need a new HD + a DVD drive ;-)\r
-*/\r
-\r
-/*Usage:\r
- istorage some.doc some.xls some.pub some.fla some.chm\r
- will extract each of these files to some.???.Contents directories\r
- these are M$ Word, Excel and Publisher and Macromedia Flash source files (ooh and a compiled HTML Help file)\r
-*/\r
-\r
-/*TODO:\r
- think up a proper name - unist??? or what??\r
- Add popt/getopt processing\r
- reverse engineer the compound file format (& chm format - Matthew T. Russotto has already done some)\r
- or just use libOLE - http://chicago.sf.net\r
- so we don't depend on M$ for the implementation\r
- Implement options for the following\r
- -i string invalid chars\r
- -f char replace invalid chars with\r
- -n char indent with this char\r
- -a string append this to each file opened\r
- various tar/unzip options\r
- --help --version\r
-*/\r
-\r
-\r
-#include <windows.h>\r
-#include <ole2.h>\r
-#include <stdio.h>\r
-#include <string.h>\r
-\r
-\r
-struct OPTIONS{\r
- char fixchar;\r
- char* invalidchars;\r
- char indentchar;\r
- char* appendstring;\r
-} options = {'.',"<>|/\\\"",'\t',".Contents"};\r
-\r
-HRESULT r;\r
-\r
-DWORD level = 0;\r
-\r
-//These next few bits are from a sample available from http://www.keyworks.net/code.htm (see http://helpware.net/delphi/index.html for a Delphi sample - need to join a yahoo group first - example 10 is the one to look at)\r
-//This stuff is supposed to be documented in the MSDN, but I only found 1 page that references ITStorage & that is an error codes list\r
-DEFINE_GUID(CLSID_ITStorage, 0x5d02926a, 0x212e, 0x11d0, 0x9d, 0xf9, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);\r
-DEFINE_GUID(IID_ITStorage, 0x88cc31de, 0x27ab, 0x11d0, 0x9d, 0xf9, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);\r
-\r
-const GUID CLSID_ITStorage = { 0x5d02926a, 0x212e, 0x11d0, { 0x9d, 0xf9, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec } };\r
-const GUID IID_ITStorage = { 0x88cc31de, 0x27ab, 0x11d0, { 0x9d, 0xf9, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec} };\r
-\r
-typedef struct _ITS_Control_Data\r
-{\r
- UINT cdwControlData; // Number of DWords to follow.\r
- UINT adwControlData[1]; // Actually this will be adwControlData[cdwControlData]\r
-} ITS_Control_Data, *PITS_Control_Data;\r
-\r
-typedef enum ECompactionLev {\r
- COMPACT_DATA = 0,\r
- COMPACT_DATA_AND_PATH\r
-};\r
-\r
-DECLARE_INTERFACE_(IITStorage, IUnknown)\r
-{\r
- STDMETHOD(StgCreateDocfile) (const WCHAR* pwcsName, DWORD grfMode, DWORD reserved, IStorage** ppstgOpen) PURE;\r
- STDMETHOD(StgCreateDocfileOnILockBytes) (ILockBytes * plkbyt, DWORD grfMode, DWORD reserved, IStorage** ppstgOpen) PURE;\r
- STDMETHOD(StgIsStorageFile) (const WCHAR * pwcsName) PURE;\r
- STDMETHOD(StgIsStorageILockBytes) (ILockBytes * plkbyt) PURE;\r
- STDMETHOD(StgOpenStorage)(const WCHAR * pwcsName, IStorage * pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage ** ppstgOpen) PURE;\r
- STDMETHOD(StgOpenStorageOnILockBytes)(ILockBytes * plkbyt, IStorage * pStgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage ** ppstgOpen) PURE;\r
- STDMETHOD(StgSetTimes)(WCHAR const* lpszName, FILETIME const* pctime, FILETIME const* patime, FILETIME const* pmtime) PURE;\r
- STDMETHOD(SetControlData)(PITS_Control_Data pControlData) PURE;\r
- STDMETHOD(DefaultControlData)(PITS_Control_Data *ppControlData) PURE;\r
- STDMETHOD(Compact)(const WCHAR* pwcsName, ECompactionLev iLev) PURE;\r
-};\r
-\r
-IITStorage* ITStorage = NULL;\r
-\r
-void EnumStorage(IStorage* is);\r
-void fixpath(char* s);\r
-\r
-int main(int argc, char *argv[]){\r
- //Get an instance of the thing to call for opening chms\r
- CoInitialize(NULL);\r
- CoCreateInstance(CLSID_ITStorage, NULL, CLSCTX_INPROC_SERVER, IID_ITStorage, (void**)&ITStorage);\r
- for(int i=1;i<argc;i++){\r
- for(DWORD ii=0;ii<level;ii++)fputc(options.indentchar,stderr);\r
- fputs(argv[i],stderr);\r
- fputs(": ",stderr);\r
- DWORD len = strlen(argv[i]);\r
- DWORD wlen = MultiByteToWideChar(CP_ACP,0,argv[i],len+1,NULL,0);\r
- WCHAR* wpath = new WCHAR[len+1];\r
- if(wpath){\r
- if(MultiByteToWideChar(CP_ACP,0,argv[i],len+1,wpath,wlen)){\r
- IStorage* is = NULL;\r
- r = StgOpenStorage(wpath,NULL,STGM_READ|STGM_SHARE_EXCLUSIVE,NULL,0,&is);\r
- if( ITStorage && r != S_OK && is == NULL ){\r
- r = ITStorage->StgOpenStorage(wpath,NULL,STGM_READ|STGM_SHARE_DENY_WRITE,NULL,0,&is);\r
- fputs("StgOpenStorage failed, trying chm version...",stderr);\r
- }\r
- delete[]wpath; wpath = NULL;\r
- if( r == S_OK || is ){\r
- STATSTG ss;\r
- if(S_OK==is->Stat(&ss,STATFLAG_NONAME))fprintf(stderr,"CLSID={%8.8X-%4.4X-%4.4X-%4.4X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X} State=0x%8.8X reserved=0x%8.8X\n", ss.clsid.Data1, ss.clsid.Data2, ss.clsid.Data3, ss.clsid.Data4[0]<<8/*&0xff00*/| ss.clsid.Data4[1], ss.clsid.Data4[2], ss.clsid.Data4[3], ss.clsid.Data4[4], ss.clsid.Data4[5], ss.clsid.Data4[6], ss.clsid.Data4[7], ss.grfStateBits, ss.reserved);\r
- else fputs("Stat failed\n",stderr);\r
- char* path = new char[len+strlen(options.appendstring)+1];\r
- if(path){\r
- strcpy(path,argv[i]);\r
- strcpy(&path[len],options.appendstring);\r
- RemoveDirectory(path);\r
- if(CreateDirectory(path,NULL)||GetLastError()==ERROR_ALREADY_EXISTS){\r
- if(SetCurrentDirectory(path)){\r
- delete[]path; path = NULL;\r
- level++;\r
- EnumStorage(is);\r
- level--;\r
- SetCurrentDirectory("..");\r
- }\r
- else fputs("Could not enter - Ignoring & continuing\n",stderr);\r
- }\r
- else fputs("Could not create (directory) - Ignoring & continuing\n",stderr);\r
- delete[]path; path = NULL;\r
- }\r
- else fputs("Could not alloc memory for the ANSI pathname for the wimpy Win9$ - Ignoring & continuing\n",stderr);\r
- is->Release();\r
- }\r
- else fputs("Could not open the specified file - Ignoring & continuing\n",stderr);\r
- }\r
- else fputs("Could not convert the path to Unicode for the Unicode only StgOpenStorage - Ignoring & continuing\n",stderr);\r
- delete[]wpath; wpath = NULL;\r
- }\r
- else fputs("Could not alloc memory for the Unicode filename for the Unicode only StgOpenStorage - Ignoring & continuing",stderr);\r
- }\r
- if( ITStorage ) ITStorage->Release();\r
- CoUninitialize();\r
- fflush(stderr);//Helps with debugging\r
- return 0;\r
-}\r
-\r
-void EnumStorage(IStorage* is){\r
- IEnumSTATSTG* iess;\r
- r = is->EnumElements(0,NULL,0,&iess);\r
- if( r!= S_OK ) { fputs("Could not enumerate elements - Ignoring & continuing\n",stderr); return;}\r
- STATSTG ss;\r
- iess->Reset();\r
- for(;;){\r
- r=iess->Next(1,&ss,NULL);\r
- if( r!= S_OK ) break;\r
- for(DWORD i=0;i<level;i++)fputc(options.indentchar,stderr);\r
- fputws(ss.pwcsName,stderr);\r
- fputs(": ",stderr);\r
- fprintf(stderr,"CLSID={%8.8X-%4.4X-%4.4X-%4.4X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X} State=0x%8.8X reserved=0x%8.8X\n", ss.clsid.Data1, ss.clsid.Data2, ss.clsid.Data3, ss.clsid.Data4[0]<<8/*&0xff00*/| ss.clsid.Data4[1], ss.clsid.Data4[2], ss.clsid.Data4[3], ss.clsid.Data4[4], ss.clsid.Data4[5], ss.clsid.Data4[6], ss.clsid.Data4[7], ss.grfStateBits, ss.reserved);\r
- DWORD len = wcslen(ss.pwcsName);\r
- char* path = new char[len+1];\r
- if(path){\r
- if(WideCharToMultiByte(CP_ACP,0,ss.pwcsName,len+1,path,len+1,NULL,NULL)){\r
- fixpath(path);\r
- switch(ss.type){\r
- case STGTY_STORAGE:{\r
- IStorage* is2;\r
- r = is->OpenStorage(ss.pwcsName,NULL,STGM_READ|STGM_SHARE_EXCLUSIVE,NULL,0,&is2);\r
- CoTaskMemFree(ss.pwcsName); ss.pwcsName = NULL;\r
- if( r == S_OK || is2 ){\r
- if(CreateDirectory(path,NULL)||(r=GetLastError())==ERROR_ALREADY_EXISTS){\r
- if(r==ERROR_ALREADY_EXISTS)fputs("Already exists (directory) - using anyway\n",stderr);\r
- else fputs("Created (directory)\n",stderr);\r
- HANDLE f = CreateFile(path,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);\r
- if(f!=INVALID_HANDLE_VALUE&&f!=0/*Fucking lying MSDN*/){\r
- if(!SetFileTime(f,&ss.ctime,&ss.atime,&ss.mtime))fputs("Could not set the creation, last modification or last access time\n",stderr);\r
- CloseHandle(f);\r
- }\r
- if(SetCurrentDirectory(path)){\r
- delete[]path; path = NULL;\r
- level++;\r
- EnumStorage(is2);\r
- level--;\r
- SetCurrentDirectory("..");\r
- }\r
- else fputs("Could not enter (directory) - Ignoring & continuing\n",stderr);\r
- }\r
- else fputs("Could not create (directory) - Ignoring & continuing\n",stderr);\r
- is2->Release();\r
- }\r
- else fputs("Could not open (directory) - Ignoring & continuing\n",stderr);\r
- }break;\r
- case STGTY_STREAM:{\r
- IStream* is2;\r
- r = is->OpenStream(ss.pwcsName,NULL,STGM_READ|STGM_SHARE_EXCLUSIVE,0,&is2);\r
- CoTaskMemFree(ss.pwcsName); ss.pwcsName = NULL;\r
- if( r == S_OK ){\r
- HANDLE f = CreateFile(path,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);\r
- delete[]path; path = NULL;\r
- if(f!=INVALID_HANDLE_VALUE&&f!=0/*Fucking lying MSDN*/){\r
- if(ERROR_ALREADY_EXISTS==GetLastError())fputs("Already exists (file) - overwriting\n",stderr);\r
- else fputs("Created (file)\n",stderr);\r
- //This bit, although a bit more complex than 1 byte at a time, is way faster\r
- BYTE* p;\r
- ULARGE_INTEGER i={0};\r
- DWORD nobm = (DWORD)ss.cbSize.QuadPart, nobr, nobw;\r
- bool err;\r
- for(;;){\r
- p = (BYTE*)malloc( nobm ); if(p)break;\r
- nobm/=2; if(!nobm)break;\r
- }\r
- if(p){\r
- do{\r
- r=is2->Read(p,nobm,&nobr);\r
- if(r!=S_OK&&nobm!=nobr){fputs("Read error (file) - terminating this file\n",stderr);err=true;}//read less than asked and there was an error other than EOF - MSDN says that the compound file implementation of Read returns S_OK if the end of the stream was reached during the read\r
- nobw=0;\r
- r=WriteFile(f,p,nobr,&nobw,NULL);\r
- i.QuadPart+=nobw;\r
- if(!r||nobr!=nobw){fputs("Write error (file) - terminating this file\n",stderr);err=true;}\r
- } while (i.QuadPart<ss.cbSize.QuadPart&&!err);\r
- free(p); p = NULL;\r
- }\r
- //Note that for(uint i=randint();!i;i/=2); will always go through i=1 to i=0\r
- else{ fputs("Could not alloc even 1 byte of mem for a buffer for transferring files - please free some memory & try again - Ignoring & continuing\n",stderr); err=true;}\r
- if(!SetFileTime(f,&ss.ctime,&ss.atime,&ss.mtime))fputs("Could not set the creation, last modification or last access time - Ignoring & continuing\n",stderr);\r
- CloseHandle(f);\r
- }\r
- else fputs("Could not create (file) - Ignoring & continuing\n",stderr);\r
- is2->Release();\r
- }\r
- else fputs("Could not open (file) - Ignoring & continuing\n",stderr);\r
- }break;\r
- case STGTY_LOCKBYTES:\r
- fputs("unsupported ILockBytes object - Ignoring & continuing\n",stderr);\r
- break;\r
- case STGTY_PROPERTY:\r
- fputs("unsupported property storage object - Ignoring & continuing\n",stderr);\r
- break;\r
- default:\r
- fputs("unknown object - Ignoring & continuing\n",stderr);\r
- break;\r
- }\r
- }\r
- else fputs("Could not convert the path back to ANSI for the wimpy Win9$ - Ignoring & continuing\n",stderr);\r
- delete[]path; path = NULL;\r
- }\r
- else fputs("Could not alloc memory for the ANSI pathname for the wimpy Win9$ - Ignoring & continuing\n",stderr);\r
- CoTaskMemFree(ss.pwcsName); ss.pwcsName = NULL;\r
- }\r
- iess->Release();\r
-}\r
-\r
-void fixpath(char* s){\r
- while(*s){//*s<32 || should probably be removed on non-FAT file systems\r
- if( *s<32 || strchr(options.invalidchars,*s) )*s=options.fixchar;\r
- s++;\r
- }\r
-}
\ No newline at end of file